package org.imdm.portal.loadchecker.telnet;

import java.util.Enumeration;
import java.util.Hashtable;

public class WhoCommand extends Command {
	UserTable userTable = new UserTable();

	public WhoCommand(TelnetClientAdvance telnet) {
		super(telnet);
	}

	public String execute() throws TelnetException {

		String info = sendCommand("who");

		if (info == null)
			return "0";

		return String.valueOf(countUsers(info));
	}

	public int countUsers(String whoCmdResponse) {
		userTable.clear();
		String[] whoRecords = whoCmdResponse.split("\\n");
		for(int i=0; i<whoRecords.length; i++) {
			int idxBlank = whoRecords[i].indexOf(" ");
			if (idxBlank <=0)
				continue;
			String name = whoRecords[i].substring(0, idxBlank);
			if(!isLoginName(name))
				continue;
			userTable.incNumber(name);
        }

		userTable.descNumber(this.telnet.getUser());
		return userTable.sum();
	}
	
	public String getUserNames() {
		return userTable.toString();
	}

	public int countSumEntities() {
		return userTable.sumEntities();
	}
	/*
	 * check if the string is a valid login name
	 */
	private boolean isLoginName(String loginName) {
        if ( (null==loginName) || (loginName.length()==0) )
        	return false;
		loginName = loginName.trim();
        for(int i=0; i<loginName.length(); i++) {
		  char ch = loginName.charAt(i);
		  if ( (ch>='A') && (ch<='Z') )
			  continue;
		  if ( (ch>='a') && (ch<='z') )
			  continue;
		  if ( (ch>='0') && (ch<='9') )
			  continue;
		  // a invalid character found
		  // System.out.println("invalid char: " + ch + "\tnot a login name: " + loginName);
		  return false;
		}

        return true;
	}

	/*
	 * customized hashtable for (name, number) pair
	 */
	class UserTable extends Hashtable<String, Integer> {
		// to avoid warning
		static final long serialVersionUID = 0x23167;

		/*
		 * increase the number of a name
		 */
		public int incNumber(String name) {
			Integer numInt = (Integer)this.get(name);
			if (numInt==null) {
				this.put(name, new Integer(1));
			}
			else {
				this.put(name, new Integer(numInt.intValue()+1));
			}
			numInt = (Integer)this.get(name);
			return numInt.intValue();
		}

		/*
		 * Descrease the number of a name
		 */
		public int descNumber(String name) {
			Integer numInt = (Integer)this.get(name);
			if (numInt==null) {
				return -1;
			}

			this.put(name, new Integer(numInt.intValue()-1));

			numInt = (Integer)this.get(name);
			int num = numInt.intValue();
			if (num>0) {
				return num;
			} else {
				this.remove(name);
				return 0;
			}
		}

		/*
		 * total user number
		 */
		public int sum() {
			return this.size();
		}
		
		public int sumEntities() {
			Enumeration<Integer> en = this.elements();
			Integer total = 0;
			while ( en.hasMoreElements() ) {
				total += en.nextElement();
			}
			return total;
		}
	}
}
